package com.proxy.scanandcheck.scaner.controller;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

import com.proxy.scanandcheck.common.valueobject.ProxyRequest;
import com.proxy.scanandcheck.scaner.thread.AbstractScannerThreadPool;

@Service
@Scope("singleton")
public class ScannerController {
	
	private Future<Boolean> result = null;
	
	@Autowired
	@Qualifier("scannerThreadPoolA")
	private AbstractScannerThreadPool scannerThreadPoolA;
	
	@Autowired
	@Qualifier("scannerThreadPoolB")
	private AbstractScannerThreadPool scannerThreadPoolB;
	
	@Autowired
	@Qualifier("scannerThreadPoolC")
	private AbstractScannerThreadPool scannerThreadPoolC;
	
	@Autowired
	@Qualifier("scannerByPossibleIpThreadPool")
	private AbstractScannerThreadPool scannerByPossibleIpThreadPool;
	
	public void process(final ProxyRequest proxyRequest)
	{
		this.processByClass(proxyRequest, scannerByPossibleIpThreadPool);
		if(proxyRequest.getIpClass().equals(ProxyRequest.A_CLASS))
			this.processByClass(proxyRequest, scannerThreadPoolA);
		else if(proxyRequest.getIpClass().equals(ProxyRequest.B_CLASS))
			this.processByClass(proxyRequest, scannerThreadPoolB);
		else if(proxyRequest.getIpClass().equals(ProxyRequest.C_CLASS))
			this.processByClass(proxyRequest, scannerThreadPoolC);
		else
		{
			ProxyRequest proxyRequestA = proxyRequest.cloneProxyRequest();
			proxyRequestA.setIpClass(ProxyRequest.A_CLASS);
			
			ProxyRequest proxyRequestB = proxyRequest.cloneProxyRequest();
			proxyRequestB.setIpClass(ProxyRequest.B_CLASS);
			
			ProxyRequest proxyRequestC = proxyRequest.cloneProxyRequest();
			proxyRequestC.setIpClass(ProxyRequest.C_CLASS);
			
			this.processByClass(proxyRequestA, scannerThreadPoolA);
			this.processByClass(proxyRequestB, scannerThreadPoolB);
			this.processByClass(proxyRequestC, scannerThreadPoolC);
		}
	}
	
	public void processByClass(final ProxyRequest proxyRequest,final AbstractScannerThreadPool scannerThreadPool)
	{
		ExecutorService executorService = Executors.newSingleThreadExecutor();
		
		Callable<Boolean> task = new Callable<Boolean>() {
			public Boolean call() throws Exception {
				return scannerThreadPool.execute(proxyRequest);
			}
		};
		
		result = executorService.submit(task);
	}

	public boolean isThreadRunning() {
		return this.result != null && !this.result.isDone();
	}

}
